package com.lj.frame.menu.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.lj.frame.menu.entity.Menu;
import com.lj.frame.menu.repo.MenuRepository;
import com.lj.frame.menu.service.MenuService;
import com.lj.tools.exception.YerException;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;


@RequiredArgsConstructor
@Slf4j
@Service
public class MenuServiceImpl implements MenuService {

    private final MenuRepository menuRepository;

    /**
     * 过滤子菜单
     * */
    private List<Menu> filterChild(List<Menu> menuList, Integer pid){
        List<Menu> childList = new ArrayList<>();
        menuList.forEach( menu -> {
            if (Objects.equals(menu.getPid(), pid)){
                childList.add(menu);
                menuList.remove(menu);
            }
        });
        return childList;
    }

    private List<Menu> listConvertTree(List<Menu> allMenuList){
        List<Menu> menuList = filterChild(allMenuList, 0);
        menuList.forEach( menu -> {
            menu.setChild( filterChild(allMenuList, menu.getId()));
            if (menu.getChild().size() > 0){
                menu.getChild().forEach( child ->{
                    child.setChild( filterChild(allMenuList, child.getId()));
                });
            }
        });
        return menuList;
    }

    /**
     * 最高支持3层菜单
     * */
    @Override
    public List<Menu> getMenuTree() {
        List<Menu> allMenuList = menuRepository.lambdaQuery().orderByAsc(Menu::getPid).orderByAsc(Menu::getSort).list();
        return listConvertTree(allMenuList);
    }

    @Override
    public List<Menu> getMenuTree(List<Integer> idList) {
        if (idList == null || idList.size() == 0){
            return new ArrayList<>();
        }
        List<Menu> allMenuList = menuRepository.lambdaQuery().in(Menu::getId, idList).orderByAsc(Menu::getPid).orderByAsc(Menu::getSort).list();
       return listConvertTree(allMenuList);
    }


    @Override
    public void remove(Integer id) {
        if (Objects.isNull(id)){
            return;
        }

        Menu menu = menuRepository.getById(id);
        if (menu.getPid() == 0){
            List<Integer> pidList = menuRepository.queryChildIdListByPid(id);
            LambdaQueryWrapper<Menu> removeQuery = new LambdaQueryWrapper<>();
            removeQuery.eq(Menu::getId, id).or().eq(Menu::getPid, id);
            menuRepository.remove(removeQuery);
            if (pidList.size() == 0){
                return;
            }
            removeQuery.clear();
            removeQuery.in(Menu::getPid, pidList);
            menuRepository.remove(removeQuery);
        }else{
            LambdaQueryWrapper<Menu> removeQuery = new LambdaQueryWrapper<>();
            removeQuery.eq(Menu::getId, id).or().eq(Menu::getPid, id);
            menuRepository.remove(removeQuery);
        }
    }

    @Override
    public void remove(List<Integer> idList) throws YerException {
        if (Objects.isNull(idList) || idList.size() == 0){
            return;
        }
        List<Integer> childIdList = menuRepository.queryChildIdListByPid(idList);
        LambdaQueryWrapper<Menu> removeQuery = new LambdaQueryWrapper<>();
        removeQuery.in(Menu::getId, idList).or().in(Menu::getPid, idList);
        menuRepository.remove(removeQuery);

        if (childIdList.size() == 0){
            return;
        }
        removeQuery.clear();
        removeQuery.in(Menu::getPid, childIdList);
        menuRepository.remove(removeQuery);
    }

    @Override
    public void save(Menu menu) throws YerException {
        if (menu.getIsLink() && !StringUtils.hasLength(menu.getPath())){
            throw new YerException("链接不可为空");
        }
        if (!menu.getIsLink() && !StringUtils.hasLength(menu.getLayout())){
            throw new YerException("布局不可为空");
        }
        menuRepository.saveOrUpdate(menu);
    }

    @Override
    public Menu info(Integer id){
        return menuRepository.getById(id);
    }
}
